# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: xguo

import functools

from coin.exchange.base.kr_rest.product import NativeProduct, NormProduct
from coin.exchange.base.kr_rest.from_str import FromStrProductV1V3Mixin
from coin.exchange.okex.kr_rest.constants import (
    symbol_list,
    quote_currency_list,
    currency_list,
    active_base_currency_list,
)
from coin.exchange.okex.kr_rest.currency import OkexCurrency


@functools.lru_cache(maxsize=1024)
def convert_native_symbol_v1_to_v3(native_symbol):
  assert native_symbol in symbol_list, native_symbol
  return native_symbol.upper().replace('_', '-')


@functools.lru_cache(maxsize=1024)
def convert_native_symbol_v3_to_v1(native_symbol):
  native_symbol_v1 = native_symbol.lower().replace('-', '_')
  assert native_symbol_v1 in symbol_list, native_symbol
  return native_symbol_v1


@functools.lru_cache(maxsize=1)
def get_active_symbol_list():
  res = []
  for base in active_base_currency_list:
    for quote in quote_currency_list:
      if base != quote:
        product = OkexProduct.FromStrPair(base, quote)
        if product.native_symbol in symbol_list:
          res.append(product.native_symbol)
  return res


class OkexProduct(FromStrProductV1V3Mixin, NativeProduct):
  _exchange = "Okex"
  NativeCurrencyType = OkexCurrency

  def __init__(self, base, quote):
    assert base != quote, (base, quote)
    self._native_symbol_v1 = "%s_%s" % (base.native_currency, quote.native_currency)
    self._native_symbol_v3 = "%s-%s" % (base.native_currency_v3, quote.native_currency_v3)
    super().__init__(base, quote, self._native_symbol_v1)

  @property
  def native_symbol_v1(self):
    return self._native_symbol_v1

  @property
  def native_symbol_v3(self):
    return self._native_symbol_v3

  @classmethod
  def FromStrProductImpl(cls, product, current_datetime):
    assert type(product) == str
    assert '-' in product
    pair = product.split('-')
    assert len(pair) == 2
    base, quote = pair
    base = OkexCurrency.FromStrCurrency(base)
    quote = OkexCurrency.FromStrCurrency(quote)
    return OkexProduct(base, quote)

  @classmethod
  def FromStrNativeProductV1Impl(cls, product, current_datetime):
    product = product.lower()
    assert type(product) == str
    assert '_' in product
    pair = product.split('_')
    assert len(pair) == 2
    base, quote = pair
    base = OkexCurrency.FromStrNativeCurrency(base)
    quote = OkexCurrency.FromStrNativeCurrency(quote)
    return OkexProduct(base, quote)

  @classmethod
  def FromStrNativeProductV3Impl(cls, product, current_datetime):
    product = product.lower()
    assert type(product) == str
    assert '-' in product
    pair = product.split('-')
    assert len(pair) == 2
    assert convert_native_symbol_v3_to_v1(product) in symbol_list
    base, quote = pair
    base = OkexCurrency.FromStrNativeCurrency(base)
    quote = OkexCurrency.FromStrNativeCurrency(quote)
    return OkexProduct(base, quote)
